package cn.com.cfae.iras.doc.analyze.components.consistency;

import cn.com.cfae.iras.doc.analyze.components.BaseComponent;
import cn.com.cfae.iras.doc.analyze.components.beans.ComponentResult;
import cn.com.cfae.iras.doc.analyze.keys.UnitType;
import cn.com.cfae.iras.doc.analyze.parse.kv.KVText;
import cn.com.cfae.iras.doc.analyze.parse.kv.TextLayout;
import cn.com.cfae.iras.doc.analyze.parse.model.ChapterModel;
import cn.com.cfae.iras.doc.analyze.parse.model.DocumentModel;
import cn.com.cfae.iras.doc.analyze.parse.model.ExtractBizModel;
import cn.com.cfae.iras.doc.analyze.parse.model.ExtractItem;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by zouxun on 2018/10/29
 */
@Component("U1005")
@Scope("prototype")
public class U1005 extends BaseComponent {
    private static Logger logger = LoggerFactory.getLogger(U1005.class);

    @Autowired
    U1004 u1004;

    /**
     * @desc 核对第六章所有会计科目分析中描述的数据与三个合并报表数据是否一致
     * @return
     */
    @Override
    public List<ComponentResult> handlerM() {
        logger.info("调用U1005组件,处理M表...................");
        String chapterModelName = "M-6-1";
        String childChapterModel = "M-6-2";
        List<ComponentResult> componentResults = ruleCheck(childChapterModel,chapterModelName);
        return componentResults;
    }

    @Override
    public List<ComponentResult> handlerBM() {
        logger.info("调用U1005组件,处理BM表...................");
        String chapterModelName = "BM-6-1";
        String childChapterModel = "BM-6-2";
        List<ComponentResult> componentResults = ruleCheck(childChapterModel,chapterModelName);
        return componentResults;
    }

    @Override
    public List<ComponentResult> handlerDM() {
        logger.info("调用U1005组件,处理DM表...................");
        String chapterModelName = "DM-6-1";
        String childChapterModel = "DM-6-2";
        List<ComponentResult> componentResults = ruleCheck(childChapterModel,chapterModelName);
        return componentResults;
    }

    @Override
    public List<ComponentResult> handlerBDM() {
        logger.info("调用U1005组件,处理BDM表...................");
        String chapterModelName = "BDM-6-1";
        String childChapterModel = "BDM-6-2";
        List<ComponentResult> componentResults = ruleCheck(childChapterModel,chapterModelName);
        return componentResults;
    }

    private Map<String, Map<String, ExtractItem>> getTables(ChapterModel chapterModel,String modelName){
        ExtractBizModel extractBizModel=chapterModel.getModel(modelName);
        if(extractBizModel!=null){
            Map<String, Map<String, ExtractItem>> map = extractBizModel.getTables();
            if(MapUtils.isNotEmpty(map)){
                return map;
            }
        }
        return null;
    }

    private KVText getTableKVTextValue(Map<String, ExtractItem> map,String key){
        if(MapUtils.isNotEmpty(map)){
            ExtractItem extractItem= map.get(key);
            if(extractItem!=null){
                return extractItem.getValue();
            }
        }
        return null;
    }

    private KVText getTableKVTextKey(Map<String, ExtractItem> map,String key){
        if(MapUtils.isNotEmpty(map)){
            ExtractItem extractItem= map.get(key);
            if(extractItem!=null){
                return extractItem.getKey();
            }
        }
        return null;
    }

    private String replaceComma(String text){
//        if(text.contains(",")){
//            text=text.replace(",","");
//        }
//        if(text.contains("，")){
//            text=text.replace("，","");
//        }
        return text.replaceAll("[,|，|(|)|（|）|。|\\s]{1,}","");
    }

    private String getAmount(String text){
        String amount= null;
        String regex = "(-{0,1}\\d{1,}\\.{0,1}\\d{1,})";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);

        while (matcher.find()) {
            amount=matcher.group(0);
        }
        return amount;
    }

    private List<ComponentResult> ruleCheck(String childChapterModelName,String chapterModelName){
        List<ComponentResult> componentResults = new ArrayList<>();

        DocumentModel documentModel = super.getExtractData();

        ChapterModel chapterModel = documentModel.getChapterModel(getCatalogId());

        try{
//            chapterModel.getChildChapterModel(childChapterModelName).getExtractBizModelMap().get("ZCFZ").getTables();
//            chapterModel.getChildChapterModel(childChapterModelName).getModel("ZCFZ").getTables();
//            chapterModel.getModel("ZCFZ").getTables();

            String[] tableNameMap = new String[]{"ZCFZ","LR","XJLL"};

            if(chapterModel!=null){
                ChapterModel childChapterModel=chapterModel.getChildChapterModel(childChapterModelName);

                if(childChapterModel!=null){
                    int blankCount = 0;
                    //不一致
                    int inconformityCount = 0;
                    //一致
                    int consistentCount = 0;
                    //未识别或无法确定
                    int unidentification=0;

                    for(String tableName:tableNameMap){
                        logger.info("当前处理模块：{}",tableName);

                        Map<String, Map<String, ExtractItem>> m62MapTable=getTables(childChapterModel,tableName);
                        Map<String, Map<String, ExtractItem>> m6MapTable=getTables(chapterModel,tableName);

                        if(MapUtils.isNotEmpty(m62MapTable)){
                            Set<String> m62Years = m62MapTable.keySet();

                            for(String m62Year:m62Years){
                                Map<String, ExtractItem> map62 = m62MapTable.get(m62Year);

                                if(MapUtils.isNotEmpty(map62)){
                                    Set<String> map62Keys = map62.keySet();

                                    for(String map62Key:map62Keys){
                                        KVText map62KVTextValue = getTableKVTextValue(map62, map62Key);
                                        KVText map62KVTextKey = getTableKVTextKey(map62, map62Key);

                                        if(map62KVTextValue!=null){
                                            String map62ValueText = map62KVTextValue.getText();
                                            String map62KeyText = map62KVTextKey.getText();

                                            logger.info("==================================================================");
                                            logger.info("当前对比的会计科目：{}",map62KeyText);
                                            logger.info("年份：{}，M-6-2会计科目：{}，数值：{}", m62Year, map62KeyText, map62ValueText);

                                            String m62ItemName = childChapterModelName.concat(map62KeyText);
//                                            String m6ItemName = getCatalogId().concat(map62KeyText);
                                            String m6ItemName = chapterModelName.concat(map62KeyText);

                                            String keyword = "年份：".concat(m62Year).concat("，").concat(m62ItemName).concat("对比").concat(m6ItemName);
                                            logger.info("keyword：{}",keyword);

                                            ComponentResult componentResult = u1004.getComponentResult(getCatalogId(),getChapterId(),getRuleTitle(),keyword,"",true,getRegulationId(),childChapterModel.getStartPage(),null,"03");

                                            componentResult=setTextPosition(map62KVTextKey,componentResult,childChapterModel);

                                            if(StringUtils.isNotEmpty(map62ValueText)){

                                                if(!map62ValueText.equals("-")){
                                                    if(MapUtils.isNotEmpty(m6MapTable)){
                                                        Set<String> m6Years = m6MapTable.keySet();

                                                        int m6YearSize = m6Years.size();

                                                        int matchCount = 0;

                                                        for(String m6Year:m6Years){

                                                            if(m62Year.equals(m6Year.substring(0,4))){
                                                                logger.info("m62Year：{}，对应合并报表年份m6Year：{}",m62Year,m6Year);
                                                                Map<String, ExtractItem> map6 = m6MapTable.get(m6Year);

                                                                KVText map6KVTextValue = getTableKVTextValue(map6, map62Key);
                                                                KVText map6KVTextKey = getTableKVTextKey(map6, map62Key);

                                                                if(map6KVTextValue!=null){
                                                                    String unit = "万元";
                                                                    ExtractItem extractItem = map6.get(map62Key);
                                                                    if(extractItem!=null){
                                                                        unit = extractItem.getUnit();
                                                                    }
                                                                    logger.info("M-6合并报表单位：{}",unit);

                                                                    String map6ValueText = map6KVTextValue.getText();
                                                                    String map6KeyText = map6KVTextKey.getText();

                                                                    if(StringUtils.isNotEmpty(map6ValueText)){

                                                                        if(!map6ValueText.equals("-")){
                                                                            logger.info("年份：{}，M-6合并报表实际年份：{}，M-6会计科目：{}，数值：{}",m62Year,m6Year,map6KeyText,map6ValueText);

                                                                            map62ValueText = replaceComma(map62ValueText);
                                                                            map6ValueText = replaceComma(map6ValueText);

                                                                            BigDecimal map6ValueTextDecimal = new BigDecimal(map6ValueText);
                                                                            //四舍五入向上保留整数位
                                                                            BigDecimal map6ValueTextDecimalAfter = map6ValueTextDecimal;
                                                                            //向下保留整数位
                                                                            BigDecimal map6ValueTextDecimalDown = map6ValueTextDecimal;

                                                                            if(map62ValueText.contains("亿元")){
                                                                                BigDecimal constant = BigDecimal.valueOf(10000);
                                                                                if(unit.equals("万元")){
                                                                                    constant = BigDecimal.valueOf(10000);
                                                                                }else if(unit.equals("千元")){
                                                                                    constant = BigDecimal.valueOf(100000);
                                                                                }else if(unit.equals("元")){
                                                                                    constant = BigDecimal.valueOf(100000000);
                                                                                }
                                                                                map6ValueTextDecimalAfter = map6ValueTextDecimal.divide(constant, 2, BigDecimal.ROUND_HALF_UP);

                                                                                map6ValueTextDecimalDown = map6ValueTextDecimal.divide(constant, 2, BigDecimal.ROUND_DOWN);
                                                                                logger.info("年份：{}，会计科目：{}，M-6原值：{}，单位转换成亿元后，向上保留：{}，向下保留：{}", m62Year, map62KeyText, map6ValueTextDecimal, map6ValueTextDecimalAfter,map6ValueTextDecimalDown);
                                                                            }else if(map62ValueText.contains("万元")){
                                                                                if(unit.equals("元")){
                                                                                    map6ValueTextDecimalAfter = map6ValueTextDecimal.divide(BigDecimal.valueOf(10000), 2, BigDecimal.ROUND_HALF_UP);

                                                                                    map6ValueTextDecimalDown = map6ValueTextDecimal.divide(BigDecimal.valueOf(10000), 2, BigDecimal.ROUND_DOWN);
                                                                                    logger.info("年份：{}，会计科目：{}，M-6原值：{}，单位转换成万元后，向上保留：{}，向下保留：{}", m62Year, map62KeyText, map6ValueTextDecimal, map6ValueTextDecimalAfter,map6ValueTextDecimalDown);
                                                                                }else if(unit.equals("千元")){
                                                                                    map6ValueTextDecimalAfter = map6ValueTextDecimal.divide(BigDecimal.valueOf(10), 2, BigDecimal.ROUND_HALF_UP);

                                                                                    map6ValueTextDecimalDown = map6ValueTextDecimal.divide(BigDecimal.valueOf(10), 2, BigDecimal.ROUND_DOWN);
                                                                                    logger.info("年份：{}，会计科目：{}，M-6原值：{}，单位转换成万元后，向上保留：{}，向下保留：{}", m62Year, map62KeyText, map6ValueTextDecimal, map6ValueTextDecimalAfter,map6ValueTextDecimalDown);
                                                                                }
                                                                            }

                                                                            if(!map62ValueText.contains(".")){
                                                                                map6ValueTextDecimalAfter = map6ValueTextDecimalAfter.setScale(0, RoundingMode.HALF_UP);

                                                                                map6ValueTextDecimalDown = map6ValueTextDecimalDown.setScale(0, RoundingMode.DOWN);
                                                                                logger.info("年份：{}，会计科目：{}，M-6原值：{}，四舍五入保留整数位：{}，向下保留整数位：{}", m62Year, map62KeyText, map6ValueTextDecimal, map6ValueTextDecimalAfter,map6ValueTextDecimalDown);
                                                                            }

                                                                            BigDecimal map62ValueTextDecimalAfter = new BigDecimal(getAmount(map62ValueText));
                                                                            int num = map6ValueTextDecimalAfter.compareTo(map62ValueTextDecimalAfter);
                                                                            logger.info("开始对比，年份：{}，会计科目：{}，M-6-2：{}，M-6：{},比较结果：{}", m62Year, map62KeyText, map62ValueTextDecimalAfter, map6ValueTextDecimalAfter, num);

                                                                            if(num != 0){
                                                                                num = map6ValueTextDecimalDown.compareTo(map62ValueTextDecimalAfter);
                                                                                logger.info("开始对比，年份：{}，会计科目：{}，M-6-2：{}，M-6：{},比较结果：{}", m62Year, map62KeyText, map62ValueTextDecimalAfter, map6ValueTextDecimalDown, num);
                                                                                if(num == 0){
                                                                                    logger.info("年份：{}，会计科目：{}，前后数据一致",m62Year,map62KeyText);
                                                                                    componentResult.setPromptMessage("一致，".concat(m62ItemName).concat("：").concat(map62ValueText).concat("，").concat(m6ItemName).concat("：").concat(map6ValueText).concat(unit));
                                                                                    componentResult.setAnnotationFlag(false);
                                                                                    consistentCount++;
                                                                                }else{
                                                                                    logger.info("年份：{}，会计科目：{}，数据不一致",m62Year,map62KeyText);
                                                                                    componentResult.setPromptMessage("不一致，".concat(m62ItemName).concat("：").concat(map62ValueText).concat("，").concat(m6ItemName).concat("：").concat(map6ValueText).concat(unit));
                                                                                    inconformityCount++;
                                                                                }
                                                                            }else{
                                                                                logger.info("年份：{}，会计科目：{}，前后数据一致",m62Year,map62KeyText);
                                                                                componentResult.setPromptMessage("一致，".concat(m62ItemName).concat("：").concat(map62ValueText).concat("，").concat(m6ItemName).concat("：").concat(map6ValueText).concat(unit));
                                                                                componentResult.setAnnotationFlag(false);
                                                                                consistentCount++;
                                                                            }

                                                                        }else{
                                                                            componentResult.setPromptMessage("无法比较，已识别".concat(m62ItemName).concat("：").concat(map62ValueText).concat("，").concat(m6ItemName).concat("未披露"));
                                                                            unidentification++;
                                                                        }

                                                                    }else{
                                                                        componentResult.setPromptMessage("已识别".concat(m62ItemName).concat("：").concat(map62ValueText).concat("，未识别").concat(m6ItemName).concat("，建议人工核对"));
                                                                        unidentification++;
                                                                    }

                                                                }else{
                                                                    componentResult.setPromptMessage("已识别".concat(m62ItemName).concat("：").concat(map62ValueText).concat("，未识别").concat(m6ItemName).concat("，建议人工核对"));
                                                                    unidentification++;
                                                                }

                                                            }else{
                                                                matchCount++;
                                                            }

                                                            if(m6YearSize==matchCount){
                                                                componentResult.setPromptMessage("已识别".concat(m62ItemName).concat("：").concat(map62ValueText).concat("，未识别").concat(m6ItemName).concat("，建议人工核对"));
                                                                unidentification++;
                                                            }

                                                        }

                                                    }else{
                                                        componentResult.setPromptMessage("已识别".concat(m62ItemName).concat("：").concat(map62ValueText).concat("，未识别").concat(m6ItemName).concat("，建议人工核对"));
                                                        unidentification++;
                                                    }

                                                }else{
                                                    componentResult.setPromptMessage(m62ItemName.concat("未披露数据"));
                                                    unidentification++;
                                                }

                                            }else{
                                                componentResult.setPromptMessage("未识别".concat(m62ItemName).concat("建议人工核对"));
                                                unidentification++;
                                            }

                                            componentResults.add(componentResult);
                                        }

                                    }

                                }

                            }

                        }else{
                            blankCount++;
                        }
                    }

                    if(blankCount==3){
                        ComponentResult componentResult = u1004.getComponentResult(getCatalogId(),getChapterId(),getRuleTitle(),"核对第六章所有会计科目分析中描述的数据与三个合并报表数据是否一致","未识别".concat(childChapterModelName).concat("会计科目数据，建议人工核对"),true,getRegulationId(),3,null,"03");

                        if(childChapterModel!=null){
                            componentResult.setPageNum(childChapterModel.getStartPage());
                        }

                        componentResults.add(componentResult);
                        return componentResults;
                    }else{
                        if(componentResults.size()>0){
                            if(inconformityCount>0){
                                for(ComponentResult componentResult : componentResults) {
                                    componentResult.setExist("02");
                                }
                                return componentResults;
                            }else{
                                if(unidentification>0){
                                    for(ComponentResult componentResult : componentResults) {
                                        componentResult.setExist("03");
                                    }
                                    return componentResults;
                                }else{
                                    if(consistentCount>0){
                                        for(ComponentResult componentResult : componentResults) {
                                            componentResult.setExist("01");
                                            componentResult.setAnnotationFlag(false);
                                        }
                                        return componentResults;
                                    }
                                }
                            }
                        }
                    }

                }else{
                    ComponentResult componentResult = u1004.getComponentResult(getCatalogId(),getChapterId(),getRuleTitle(),"核对第六章所有会计科目分析中描述的数据与三个合并报表数据是否一致","未识别".concat(childChapterModelName).concat("会计科目数据，建议人工核对"),true,getRegulationId(),3,null,"03");
                    if(chapterModel!=null){
                        componentResult.setPageNum(chapterModel.getStartPage());
                    }
                    componentResults.add(componentResult);
                    return componentResults;
                }

            }else{
                ComponentResult componentResult = u1004.getComponentResult(getCatalogId(),getChapterId(),getRuleTitle(),"核对第六章所有会计科目分析中描述的数据与三个合并报表数据是否一致","未识别".concat(childChapterModelName).concat("会计科目数据，建议人工核对"),true,getRegulationId(),3,null,"03");
                componentResults.add(componentResult);
                return componentResults;
            }

        }catch (Exception e){
            logger.error(e.getMessage(),e);

            if(componentResults.size()==0){
                ComponentResult componentResult = u1004.getComponentResult(getCatalogId(),getChapterId(),getRuleTitle(),"核对第六章所有会计科目分析中描述的数据与三个合并报表数据是否一致","未识别".concat(childChapterModelName).concat("会计科目数据，建议人工核对"),true,getRegulationId(),3,null,"03");
                if(chapterModel!=null){
                    componentResult.setPageNum(chapterModel.getStartPage());
                }
                componentResults.add(componentResult);
                return componentResults;
            }

        }

        return componentResults;
    }


    public ComponentResult setTextPosition(KVText kvText,ComponentResult componentResult,ChapterModel chapterModel){
        TextLayout textLayout=kvText.getTextLayout();
        if(textLayout!=null){
            List<ComponentResult.TextPosition> textPositionList = new ArrayList<>();
            ComponentResult.TextPosition textPosition = new ComponentResult().new TextPosition();
            textPosition.setX(textLayout.getLeft());
            textPosition.setY(textLayout.getTop());
            textPosition.setContent(textLayout.getText());
            textPositionList.add(textPosition);
            componentResult.setPageNum(textLayout.getPageNumber());
            componentResult.setTextPosition(textPositionList);
        }else{
            if(chapterModel!=null){
                componentResult.setPageNum(chapterModel.getStartPage());
            }
        }
        return componentResult;
    }

}
